protobuf的安装及使用

Linux下protobuf的安装过程&简单使用。
protobuf是google开发的一个灵活的、高效的用于序列化数据的协议。相比较XML和JSON格式,protobuf更小、更快、更便捷。

安装

  • 下载链接:https://github.com/protocolbuffers/protobuf/releases ,我是用c++,所以下载protobuf-cpp就行了。
  • tar -xzvf protobuf-*.tar.gz
  • cd protobuf-*
  • ./configure –prefix=/usr/local/protobuf
  • make (可能会等好一段时间)
  • make check
  • make install
  • vim /etc/profile

    1
    2
    export PATH=$PATH:/usr/local/protobuf/bin/
    export PKG_CONFIG_PATH=/usr/local/protobuf/lib/pkgconfig/
  • source /etc/profile

  • protoc –version #测试是否安装成功

使用方法

1
cd ~/test
  • vim address.proto

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    package tutorial;

    message Persion {
    required string name = 1;
    required int32 age = 2;
    }

    message AddressBook {
    repeated Persion persion = 1;
    }
  • protoc -I=. –cpp_out=. address.proto #在当前文件夹生成cpp的.h和.cc文件

  • vim write.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
#include <iostream>
#include <fstream>
#include <string>
#include "address.pb.h"

using namespace std;

void PromptForAddress(tutorial::Persion *persion) {
cout << "Enter persion name:" << endl;
string name;
cin >> name;
persion->set_name(name);

int age;
cin >> age;
persion->set_age(age);
}

int main(int argc, char **argv) {
//GOOGLE_PROTOBUF_VERIFY_VERSION;

if (argc != 2) {
cerr << "Usage: " << argv[0] << " ADDRESS_BOOL_FILE" << endl;
return -1;
}

tutorial::AddressBook address_book;

{
fstream input(argv[1], ios::in | ios::binary);
if (!input) {
cout << argv[1] << ": File not found. Creating a new file." << endl;
}
else if (!address_book.ParseFromIstream(&input)) {
cerr << "Filed to parse address book." << endl;
return -1;
}
}

// Add an address
PromptForAddress(address_book.add_persion());

{
fstream output(argv[1], ios::out | ios::trunc | ios::binary);
if (!address_book.SerializeToOstream(&output)) {
cerr << "Failed to write address book." << endl;
return -1;
}
}

// Optional: Delete all global objects allocated by libprotobuf.
//google::protobuf::ShutdownProtobufLibrary();

return 0;
}
  • read.cpp

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    #include <iostream>
    #include <fstream>
    #include <string>
    #include "address.pb.h"

    using namespace std;

    void ListPeople(const tutorial::AddressBook& address_book) {
    for (int i = 0; i < address_book.persion_size(); i++) {
    const tutorial::Persion& persion = address_book.persion(i);

    cout << persion.name() << " " << persion.age() << endl;
    }
    }

    int main(int argc, char **argv) {
    //GOOGLE_PROTOBUF_VERIFY_VERSION;

    if (argc != 2) {
    cerr << "Usage: " << argv[0] << " ADDRESS_BOOL_FILE" << endl;
    return -1;
    }

    tutorial::AddressBook address_book;

    {
    fstream input(argv[1], ios::in | ios::binary);
    if (!address_book.ParseFromIstream(&input)) {
    cerr << "Filed to parse address book." << endl;
    return -1;
    }
    input.close();
    }

    ListPeople(address_book);

    // Optional: Delete all global objects allocated by libprotobuf.
    //google::protobuf::ShutdownProtobufLibrary();

    return 0;
    }
  • 编译两个文件

    1
    2
    g++ address.pb.cc write.cpp -o write `pkg-config --cflags --libs protobuf`
    g++ address.pb.cc read.cpp -o read `pkg-config --cflags --libs protobuf`
  • 运行

    1
    2
    3
    4
    ./write data.txt
    aaa 999
    ./read data.txt
    aaa 999

问题

  • 运行write时,提示找不到动态链接库
    1
    2
    添加安装路径下的lib路径
    export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/protobuf/lib

编码示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
package test
message hello {
int32 id = 1;//id=300
string str = 2;//str="hello"
}

key 1 >> 1000|0 >> 1000 >> 08
yield 300 >> ‭0010 010 1100‬ >> 010 1100 000 0010 >> 1010 1100 0000 0010 >> ac 02

key 2 >> 10000|10 >> 0001 0010 >> 12
yield hello 长度05
>> 68 65 6c 6c 6f
>> 01101000 01100101 01101100 01101100 01101111
>>
result: 08 ac 02 12 05 68 65 6c 6c 6f

参考

欢迎与我分享你的看法。
转载请注明出处:http://taowusheng.cn/